package com.chenyu.service.impl;

import com.chenyu.client.UserClients;
import com.chenyu.service.IVerifyCodeService;
import com.chenyu.util.AjaxResult;
import com.chenyu.util.StrUtils;
import com.chenyu.util.VerifyCodeUtils;
import org.apache.commons.lang.StringUtils;
import org.aspectj.weaver.loadtime.Aj;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author 晴
 * @version 1.0
 * @description:
 * @date 2024/6/18 12:18
 */
@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserClients  userClients;

/*    @Autowired
    private UserMapper userMapper;*/

    /**
    * @Description:  生成图形验证码 返回base64的图片流
    * @Param: [key]
    * @Return: com.chenyu.base.utils.AjaxResult
    * @Author: 晴
    * @Data: 2024/6/18
    */
    public AjaxResult getImgCode(String key) {
        AjaxResult ajaxResult = new AjaxResult();
        try {
            //1.生成图片中的验证码
            String verifyCode = StrUtils.getComplexRandomString(4);
            //2.将生成的验证码保存到redis中 5分钟后过期
            redisTemplate.opsForValue().set(key,verifyCode,5, TimeUnit.MINUTES);
            //3.生成图形验证码的base64的图片流
            String base64Code = VerifyCodeUtils.VerifyCode(80, 30, verifyCode);
            ajaxResult.setData(base64Code);
        } catch (IOException e) {
            ajaxResult.setSuccess(false);
            ajaxResult.setMsg("验证码生成失败！！！");
            e.printStackTrace();
        }
        return ajaxResult;
    }


    /**
    * @Description: 获取短信验证码
    * @Param: [params]
    * @Return: com.chenyu.base.utils.AjaxResult
    * @Author: 晴
    * @Data: 2024/6/18
    */
    public AjaxResult sendSms(Map<String, String> params) {
        String mobile = params.get("mobile"); //手机号
        String imageCode = params.get("imageCode"); //验证码
        String imageCodeKey = params.get("imageCodeKey"); //redis中储存验证码的KEY值
        //1.检查前端传入参数是否为空值
        if (StringUtils.isBlank(mobile) || StringUtils.isBlank(imageCode) || StringUtils.isBlank(imageCodeKey)){
            return AjaxResult.error("输入参数有误，请检查后重试！");
        }
        //2.若redis中不存在图形验证码(验证码已过期)或验证码的不合法
        Object redisCode = redisTemplate.opsForValue().get(imageCodeKey);
        if (redisCode == null){
            return  AjaxResult.error("验证码已过期！");
        }
        //验证码的不合法
        if (!StringUtils.equalsIgnoreCase(imageCode, redisCode.toString())){
            return AjaxResult.error("验证码错误！");
        }

        //3.手机号是否已经注册
                /*User user = userMapper.getByPhone(mobile);
        if (user != null){
            //表示该手机号已经注册
            return ajaxResult.setSuccess(false).setMessage("该账号已注册！");
        }*/
        AjaxResult result = userClients.getByPhone(mobile);
        if (result.getData() != null){
            //表示该手机号已经注册
            return AjaxResult.error("该账号已注册！");
        }


        /*
         * SMS:18244229575={code:”1234” , sendTime: “mills”}
         */
        //4.生成手机验证码
        Map<String,Object> mobileMap = (Map<String,Object>)redisTemplate.opsForHash().entries("reg:" + mobile);
        String code = null;
        if (mobileMap == null || mobileMap.size() == 0){
            //4.1 手机验证码不存在或已经过期，需要重新生成验证码 并发送
            code = StrUtils.getRandomString(6);
            mobileMap.put("code",code);
            mobileMap.put("sendTime",System.currentTimeMillis());
        }else {
            //4.2 手机验证码还在重发时间内 需要给出提示
            Long sendTime = (Long)mobileMap.get("sendTime");
            long nowTime = System.currentTimeMillis();
            if ( (nowTime - sendTime) < 1000 * 60){
                //表示60s内又请求了一次发送验证码
                return AjaxResult.error("请不要频繁发送验证码，请稍后再试！");
            }
            //4.3 已经过了60s 但是验证码还未过期 又请求又请求了一次发送验证码
                //重新设置验证码的发送的时间 并发送原来的验证码
            code = (String) mobileMap.get("code");
            mobileMap.put("sendTime",System.currentTimeMillis());
        }
        //将验证码存储在redis中
        redisTemplate.opsForHash().putAll("reg:" + mobile, mobileMap);
        //设置验证码过期时间
        redisTemplate.expire("reg:" + mobile,5,TimeUnit.MINUTES);
        //重发验证码
//        SendMsgWebchineseUtil.sendMsgCode(mobile, "验证码：" + code);
        return new AjaxResult();
    }

    /**
    * @Description: 微信登录绑定手机号时获取验证码
    * @Param: [params]
    * @Return: com.chenyu.base.utils.AjaxResult
    * @Author: 晴
    * @Data: 2024/6/20
    */
    public AjaxResult bindSms(Map<String, String> params) {
        AjaxResult ajaxResult = new AjaxResult();

       /* String mobile = params.get("mobile");
        //1.手机号非空判断
        if ( StringUtils.isBlank(mobile) ){
            return ajaxResult.setSuccess(false).setMessage("参数异常，请检查后重试！");
        }
        //2.发送验证码
        //2.1判断redis内是否存在验证码
        Map bindMap = redisTemplate.opsForHash().entries("bind:" + mobile);

        String code = null;
        //2.1.1若不存在验证码，表示验证码已经过期，需要重新生成验证码，发送给用户
        if (bindMap == null || bindMap.size() == 0){
            code = StrUtils.getRandomString(6);
            bindMap.put("code",code);
            bindMap.put("sendTime",System.currentTimeMillis());
        }else {
            //2.1.2若存在验证码，且验证码在重发时间内，需要提示用户不要频繁操作
            Long sendTime = (Long) bindMap.get("sendTime");
            long nowTime = System.currentTimeMillis();
            if ( (nowTime-sendTime) < 1000 * 60 ){
                return ajaxResult.setSuccess(false).setMessage("请不要频繁发送验证码，请稍后再试！");
            }
            //2.1.3若存在验证码,但是已经过了重发时间内，需要重置原来的验证码的时间，再发送给用户
            bindMap.put("sendTime",System.currentTimeMillis());
        }
        //将验证码存储在redis中
        redisTemplate.opsForHash().putAll("bind:" + mobile, bindMap);
        //设置验证码过期时间
        redisTemplate.expire("bind:" + mobile,5,TimeUnit.MINUTES);
//        SendMsgWebchineseUtil.sendMsgCode(mobile,"验证码：" + code);*/
        return ajaxResult;
    }
}
